#ifndef __TASK_MANAGER_NODE_H__
#define __TASK_MANAGER_NODE_H__

#include <ros/package.h>
#include <tasks_manager/base_define.h>
#include <tasks_manager/msg_convert.h>
#include <tasks_manager/data_compatible.h>
#include <tasks_manager/log_save.h>
#include <tasks_manager/task_gen_interface.h>
#include <tasks_manager/tasks_db.h>
#include "../file_manager/file_manager.h"
#include "../file_manager/date_format.h"

#include <deque>
#include <thread>
#include <unordered_map>
using namespace std;

class TaskManagerNode{
    public:
        TaskManagerNode(tf2_ros::Buffer* tf_buffer);
        ~TaskManagerNode();

        // 日志发布
        void LogPub(string log_level, string msg);
        // 日志发布
        void LogPub(string log_level, vector<string> msgs);

        // 更新任务报告参数配置
        void UpdateTaskReportConfig();


        /*******************************************
         * 离线任务管理
         *******************************************/
        // 任务生成处理
        Status TaskGenerateHandle(TaskSingle& task_single, bool save_task);
        // 任务删除处理 删除单个任务
        Status TaskSingleDelete(string task_name, string map_name);
        // 任务删除处理 删除当前地图下所有单个任务
        Status TaskSingleDeleteForNapName(string map_name);
        // 任务删除处理 删除所有地图下单个任务
        Status TaskSingleDeleteAll();
        // 任务重命名
        Status TaskSingleRename(string task_name, string map_name, string new_task_name);
        // 更改单个任务, 重命名、修改清洁模式、外设模式、清洁速度
        Status TaskSingleUpdate(string task_name, string map_name, TaskBase task_base);
        // 任务更新路径
        Status TaskSingleUpdatePath(string task_name, string map_name);
        // 设置置顶属性
        Status TaskSingleSetTop(string task_name, string map_name, bool is_top);
        // 单个任务更新地图名称处理
        Status TaskSingleUpdateMapName(string map_name, string new_map_name);
        // 任务信息查询
        Status TaskSingleQuery(string task_name, string map_name, TaskSingle& task_single);
        // 任务列表查询 指定地图
        Status TaskSingleListForMapName(string map_name, vector<TaskSingle>& task_singles);
        // 所有任务列表查询 不同地图
        Status TaskSingleListForAllMap(vector<TaskSingle>& task_singles);
        // 组合任务添加
        Status TaskGroupAdd(TaskGroup& task_group);
        // 组合任务删除
        Status TaskGroupDelete(string group_name);
        // 删除所有组合任务
        Status TaskGroupDeleteAll();
        // 组合任务更新名称
        Status TaskGroupRename(string task_group_name, string new_task_group_name);
        // 更新当前地图下单个任务路径
        Status TaskSingleUpdatePathWithMapName();
        // 设置置顶属性
        Status TaskGroupSetTop(string task_group_name, bool is_top);
        // 组合任务路径更新
        Status TaskGroupUpdatePath(string task_group_name);
        // 补全组合任务下任务列表全部信息，更新单个任务信息
        void TaskGroupComplete(TaskGroup& task_group);
        // 组合任务信息查询
        Status TaskGroupQuery(string task_group_name, TaskGroup& task_group);
        // 更新所有组合任务下任务列表信息，用于单个任务重命名或删除操作
        // is_delete true 删除，false 更新
        void TaskGroupUpdateTaskList(string map_name, string old_name, string new_name, bool is_delete);
       // 更新组合任务下任务列表地图名称，用于地图删除/重命名操作
        // is_delete true 删除，false 更新
        void TaskGroupUpdateMapName(string map_name, string new_map_name, bool is_delete);
        // 组合任务列表查询
        Status TaskGroupList(vector<TaskGroup>& task_groups);
        // 定时任务添加
        Status TimerTaskAdd(TimerTask& timer_task);
        // 定时任务删除
        Status TimerTaskDelete(string timer_task_name);
        // 删除所有定时任务
        Status TimerTaskDeleteAll();
        // 删除指定地图下定时任务
        Status TimerTaskDeleteByMapName(string map_name);
        // 重命名地图，同步定时任务操作
        Status TimerTaskUpdateMapName(string map_name, string new_map_name);
        // 定时任务更新名称
        Status TimerTaskUpdate(TimerTask& timer_task, TimerTask& new_timer_task);
        // 设置置顶属性
        Status TimerTaskSetTop(string timer_task_name, bool is_top);
        // 定时任务信息查询
        Status TimerTaskQuery(string timer_task_name, TimerTask& timer_task);
        // 定时任务列表查询
        Status TimerTaskList(vector<TimerTask>& timer_tasks);
        // 更新定时任务下所有组合任务，用于组合任务删除或重命名操作
        // is_delete true 删除，false 更新
        void UpdateTimerTaskTaskGroupList(string old_name, string new_name, bool is_delete);
        // 获取地图列表
        vector<string> GetMapList();
        // 兼容数据并备份数据库文件
        void TaskDataCompatible(string cache_dir);
        
        /*******************************************
         * 在线任务管理
         *******************************************/
            /*******************************************
             * 查询地图基础信息
             *******************************************/
            // 查询地图信息
            void QueryMapBaseInfo(string map_name, v3_msgs::MapBase& map_base);

            /*******************************************
             * 默认任务组构造 tasks_deque.cpp
             *******************************************/
            // 是P2P任务
            bool IsP2PTask(TaskType type);
            // 是充电任务
            bool IsChargingTask(TaskType type);
            // 构造P2P任务 p2p_move
            TaskGroup GenP2PTask(geometry_msgs::Pose goal);
            // 构造梯控转移任务 trans_floor
            TaskGroup GenTransTask(v3_msgs::MapBase map_base, v3_msgs::MapBase next_map_base);
            // 构造回桩任务 charging
            TaskGroup GenChargingTask(geometry_msgs::Pose goal);
            // 生成默认充电桩回桩任务 charging   用于自动回桩和手动下发
            Status GenDefaultChargingTask(TaskGroup& task_group);
            // 生成充电桩回桩任务(默认充电桩查询失败，前往最近充电桩) charging  用于自动回桩
            Status GenNearestChargingTask(TaskGroup& task_group);
            // 生成默认停靠点 用于自动回桩
            Status GenDefaultStopTask(TaskGroup& task_group);
            // 生成最近停靠点任务 用于自动回桩
            Status GenNearestStopTask(TaskGroup& task_group);

            /*******************************************
             * 任务队列管理 tasks_deque.cpp
             *******************************************/
            // 生成任务ID
            string GenerateId(); 
            // 任务队列插入
            void PushTaskGroup(TaskGroup task_group);
            // 查询当前正在执行单个任务的task_id和所在任务队列首个组合任务的索引
            pair<string, int> GetExecTaskSingleInfo();
            // 查询组合任务所在任务队列的索引
            int GetTaskGroupIndex(string group_id);
            // 删除组合任务 基于group_id
            bool DeleteTaskGroup(string group_id);
            // 获取指定任务索引数据
            bool GetOnlineTaskIndex(string task_id, string group_id, int& task_index, int&group_index);

            /*******************************************
             * 获取机器人位姿 tasks_online_manager.cpp
             *******************************************/
            // 获取TF数据
            bool GetTFPose(string father_id, string child_id, geometry_msgs::PoseStamped& pose_stamp, ros::Time time);
            // 获取TF数据
            bool GetTFPose(string father_id, string child_id, geometry_msgs::PoseStamped& pose_stamp);

            /*******************************************
             * 发布报警信息 tasks_online_manager.cpp
             *******************************************/
            // 生成报警消息
            cln_msgs::AlarmMsg GenClnAlarmMsg(int level, long event_code, string event_key);
            // 发布报警消息
            void PubAlarmMsg(int level, string event_key);
            
            /*******************************************
             * 任务控制 -> 导航模块 tasks_online_manager.cpp
             *******************************************/
            // 请求任务控制
            Status RequestTaskControl(TaskSingle& task_single, int option);
            // 暂停任务 -> 导航模块
            Status PauseTask2NavModule();
            // 恢复任务 -> 导航模块
            Status ResumeTask2NavModule();
            // 取消当前任务 -> 导航模块
            Status CancelTask2NavModule(TaskSingle& task_single);
            // 开始执行任务 -> 导航模块
            Status StartTask2NavModule(TaskSingle& task_single);
            // 终止任务 -> 导航模块
            Status TerminatedTask2NavModule(TaskSingle& task_single);

            /*******************************************
             * 清洁报告 tasks_report.cpp
             *******************************************/
            // 任务组开始/结束记录
            Status TaskGroupRecord(TaskGroup& task_group, bool is_start, vector<TaskRecord>& task_records);
            // 单个任务开始/结束记录
            Status TaskSingleRecord(TaskGroup& task_group, bool is_start, string curr_task_id, vector<TaskRecord>& task_records);
            // 查询指定组合任务记录，需要group_id
            Status TaskGroupReportQuery(string group_id, vector<TaskRecord>& task_records);
            // 查询组合任务记录（基于时间范围和页数）
            Status TaskGroupReportQuery(ros::Time start_time, ros::Time end_time, int page, int page_size,
                bool is_all_info, vector<TaskRecord>& task_records);
            
            /*******************************************
             * 组合任务运行管理 tasks_online_manager.cpp
             *******************************************/
            // 取消正在执行的首个任务
            void CancelFrontTaskGroup();
            // 首个任务是否全部完成
            bool IsFronTaskGroupFinished();
            // 取消指定组合任务
            void CancelTaskGroup(TaskGroup& taskgroup);
            // 取消所有任务
            void CancelAllTask();
            // 检测当前状态，任务是否可以正常下发
            bool CheckStatusIsValid(std::shared_ptr<TaskSingle> task_single_ptr);
            // 任务组结束，自动回桩或回停靠点处理
            void TaskEmptyAndGoHome();
            // 单个任务结束管理
            void TaskFinishedHandle(TaskSingle task_single_finished);
            // 更新任务队列数据, 并发布数据
            void OnlineTaskDequeUpdatePub();
            // 在线任务状态发布
            void OnlineTaskPublish(TaskEcho& task_echo);
            // 在线任务状态发布 空闲状态
            void OnlineTaskPublishIdle();
            // 通知上传云平台
            // void UploadGroup(string group_id);
            // 任务监控函数
            void TasksMonitor();
            // 返回当前需要执行任务
            std::shared_ptr<TaskSingle> FindOnlineTaskSingleExec(bool& is_first);
            // 发布语音
            void PublishWorkVoice();
            // 单个任务结束处理
            void TaskSingleEndHandle(TaskGroup task_group, string task_id, bool need_record);
            // 任务组结束处理
            void TaskGroupEndHandle(TaskGroup task_group, bool need_record);
            // 获取当前最新任务组数据
            void GetCurrTaskGroup(string group_id, TaskGroup& task_group);
            // 更新单个任务回传状态数据
            void UpdateTaskEcho(string group_id, TaskSingle& task_single);
            // 删除已完成的任务组
            void RemoveFinishedTaskGroup(string group_id);

            /*******************************************
             * 定时任务运行管理 timertask_running.cpp
             *******************************************/
            // 获取当前时间信息
            pair<string,string> GetNowTimeInfo();
            // 定时任务运行检测
            void TimerTaskRunning();

    private:
        // 地图名称订阅
        void MapNameSub(const std_msgs::StringConstPtr& msg);
        // 地图信息订阅
        void MapInfoSub(const v3_msgs::MapInfoConstPtr& msg);
        // P2P订阅
        void P2PMoveSub(const v3_msgs::P2PMoveConstPtr& msg);
        // 回桩订阅
        void GoHomeSub(const v3_msgs::GoHomeConstPtr& msg);
        // 在线任务控制订阅
        void OnlineTaskCtrlSub(const v3_msgs::OnlineTaskCtrlConstPtr& msg);
        // 任务回传订阅
        void TaskEchoSub(const v3_msgs::TaskEchoConstPtr& msg);
        // 位置确认开关订阅
        void RobotSafeSub(const std_msgs::BoolConstPtr& msg);
        // 硬件状态订阅
        void HardwareStateSub(const cln_msgs::HardwareStateConstPtr& msg);
        // 地图状态订阅
        void MapStatusSub(const cln_msgs::MapStatusConstPtr& msg);
        // 参数更新订阅
        void ParamsUpdateSub(const cln_msgs::StringArrayConstPtr& msg);
        // 地图列表订阅
        void MapListSub(const v3_msgs::MapListConstPtr& msg);
        // 单个任务服务
        bool TaskSingleServer(v3_msgs::TaskSingleManagerRequest &req, v3_msgs::TaskSingleManagerResponse &res);
        // 组合任务服务
        bool TaskGroupServer(v3_msgs::TaskGroupManagerRequest &req, v3_msgs::TaskGroupManagerResponse &res);
        // 定时任务服务
        bool TimerTaskServer(v3_msgs::TimerTaskManagerRequest &req, v3_msgs::TimerTaskManagerResponse &res);
        // 任务生成服务
        bool TaskGenerateServer(v3_msgs::TaskGenerateManagerRequest &req, v3_msgs::TaskGenerateManagerResponse &res);
        // 任务完成记录服务
        bool TaskFinishedRecordServer(v3_msgs::TaskFinishedRecordRequest &req, v3_msgs::TaskFinishedRecordResponse &res);
        // 任务组完成记录服务
        bool TaskGroupReportServer(v3_msgs::TaskReportManagerRequest &req, v3_msgs::TaskReportManagerResponse &res);

    private:        
        ros::NodeHandle __nh;
        tf2_ros::Buffer* const __tf_buffer;
        ros::Publisher __log_pub;
        ros::Publisher __voice_pub;
        ros::Publisher __alarm_event_pub;       //报警发布
        ros::Publisher __online_task_single_pub;
        ros::Publisher __online_task_group_pub;
        ros::Publisher __online_tasks_deque_pub;
        // ros::Publisher __notification_record_upload;
        ros::Subscriber __map_name_sub;
        ros::Subscriber __map_info_sub;
        ros::Subscriber __p2p_move_sub;
        ros::Subscriber __go_home_sub;
        ros::Subscriber __onlinetask_ctrl_sub;
        ros::Subscriber __task_echo_sub;
        ros::Subscriber __robot_safe_sub;                   //位置确认开关
        ros::Subscriber __hardware_state_sub;               //硬件状态
        ros::Subscriber __map_status_sub;                   //地图状态
        ros::Subscriber __params_update_sub;                //参数订阅更新
        ros::Subscriber __map_list_sub;
        ros::ServiceServer __task_generate_server;
        ros::ServiceServer __task_single_server;
        ros::ServiceServer __task_group_server;
        ros::ServiceServer __timer_task_server;
        ros::ServiceServer __task_finished_record_server;   //单个任务结束数据存储服务  导航控制模块上传
        ros::ServiceServer __taskgroup_record_server;
        ros::ServiceClient __task_controller_client;       //在线任务控制服务  对接导航控制模块    待补全
        ros::ServiceClient __report_record_client;         //任务报告生成服务  对接路径规划模块    待补全
        ros::ServiceClient __map_info_client;              //地图信息服务
        ros::ServiceClient __cloudsync_record_client;              //通知任务报告上传记录

    private:
        LogSave __log_save;
        DataCompatible __data_compatible;
        MsgConvert __msg_convert;
        PathGenInterface __path_gen_interface;
        boost::shared_ptr<TaskDB> __task_db_ptr;

        string __db_dir,__tasks_db,__tasks_record_db;
        string __cache_dir;
        string __maps_dir;
        string __map_name;
        boost::shared_ptr<const v3_msgs::MapInfo> __map_info_ptr;
        boost::shared_ptr<const cln_msgs::HardwareState> __hardware_state_ptr;
        boost::shared_ptr<const cln_msgs::MapStatus> __map_status_ptr;
        boost::shared_ptr<const v3_msgs::TaskEcho> __task_echo_ptr;
        boost::shared_ptr<const v3_msgs::MapList> __map_list_ptr;
        deque<std::shared_ptr<TaskGroup>> __online_tasks_deque;     //在线任务队列
        bool __robot_safe;          //位置确认开关状态
        bool __robot_lock_state;    //锁机状态
        vector<string> __week_days; //周期表
        int __all_finished_doing;
        unordered_map<string, TaskGroup> __task_finished_cache;     //任务组结束数据缓存
        bool __path_gen_use_cln_msgs;   //路径生成是否使用cln_msgs
        WorkVoice __work_voice;
        boost::shared_ptr<TaskSingle> __curr_task_single;
        int __timertask_cancel_charge,__timertask_no_dc_charge;
        int __power_gohome;
        string __last_map_name = "";        //上次地图加载名称
        string __report_config_yaml_file = "";      //任务报告配置文件
        TaskReportConfig __task_report_config;      //任务报告配置参数
        vector<string> __translation_key_list;  
        
};

#endif